-- SPDX-License-Identifier: GPL-3.0-or-later

local extension = Package("ling2")
extension.extensionName = "lingling"

local U = require "packages/utility/utility"

local yingzheng = General(extension, "lingling__yingzheng", "qin", 4)
local julun = fk.CreateTriggerSkill{
  name = "lingling__julun",
  anim_type = "switch",
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if table.find(player.room.alive_players, function (p)
        return p.hp == player:getMark("@lingling__julun")
      end) then
        return true
      else
        return table.find(player.room.alive_players, function (p)
          return not p:isWounded() and math.abs(p.hp - player:getMark("@lingling__julun")) == 1
        end)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "#lingling__julun1-invoke:::"..player:getMark("@lingling__julun")
    local targets = table.filter(room.alive_players, function (p)
      return p.hp == player:getMark("@lingling__julun")
    end)
    if #targets == 0 then
      prompt = "#lingling__julun2-invoke:::"..player:getMark("@lingling__julun")
      targets = table.filter(room.alive_players, function (p)
        return not p:isWounded() and math.abs(p.hp - player:getMark("@lingling__julun")) == 1
      end)
    end
    local to = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, prompt, self.name, true)
    if #to > 0 then
      self.cost_data = {tos = to}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    if to.hp > player:getMark("@lingling__julun") then
      room:changeMaxHp(to, -1)
    elseif to.hp < player:getMark("@lingling__julun") then
      room:changeMaxHp(to, 1)
      if to:isWounded() then
        room:recover{
          who = to,
          num = 1,
          recoverBy = player,
          skillName = self.name,
        }
      end
    end
    if not to.dead then
      room:damage{
        from = player,
        to = to,
        damage = 1,
        skillName = self.name,
      }
    end
    if not player.dead and player:getMark("@lingling__julun") > 0 then
      if player:getMark("@lingling__julun") < 5 then
        room:addPlayerMark(player, "@lingling__julun", 1)
      else
        room:setPlayerMark(player, "@lingling__julun", 3)
      end
    end
  end,

  on_acquire = function (self, player)
    player.room:setPlayerMark(player, "@lingling__julun", 3)
  end,
  on_lose = function (self, player)
    player.room:setPlayerMark(player, "@lingling__julun", 0)
  end,
}
local quche = fk.CreateActiveSkill{
  name = "lingling__quche",
  anim_type = "offensive",
  card_num = 0,
  target_num = 0,
  prompt = "#lingling__quche",
  interaction = function(self)
    local choices = {"draw2"}
    if table.find(Fk:currentRoom().alive_players, function (p)
      return not p:isNude()
    end) then
      table.insert(choices, "discard2")
    end
    return UI.ComboBox {choices = choices}
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:doIndicate(player.id, table.map(room.alive_players, Util.IdMapper))
    for _, p in ipairs(room:getAlivePlayers()) do
      if not p.dead then
        if self.interaction.data == "draw2" then
          p:drawCards(2, self.name)
        else
          room:askForDiscard(p, 2, 2, true, self.name, false)
        end
      end
    end
    if self.interaction.data == "draw2" then
      local targets = table.filter(room.alive_players, function (p)
        return table.every(room.alive_players, function (q)
          return p:getHandcardNum() >= q:getHandcardNum()
        end)
      end)
      for _, p in ipairs(room:getAlivePlayers()) do
        if not p.dead then
          if table.contains(targets, p) then
            p:drawCards(1, self.name)
          end
        end
      end
    else
      local targets = table.filter(room.alive_players, function (p)
        return table.every(room.alive_players, function (q)
          return p:getHandcardNum() <= q:getHandcardNum()
        end)
      end)
      for _, p in ipairs(room:getAlivePlayers()) do
        if not p.dead then
          if table.contains(targets, p) then
            room:askForDiscard(p, 1, 1, true, self.name, false)
          end
        end
      end
    end
  end,
}
yingzheng:addSkill(julun)
yingzheng:addSkill(quche)
Fk:loadTranslationTable{
  ["lingling__yingzheng"] = "嬴政",
  ["#lingling__yingzheng"] = "千古祖龙",
  ["illustrator:lingling__yingzheng"] = "珊瑚虫",
  ["designer:lingling__yingzheng"] = "伶",

  ["lingling__julun"] = "巨轮",
  [":lingling__julun"] = "转换技，回合开始时，你可以对一名体力为①3②4③5的角色造成1点伤害。若没有符合条件的角色，且有任意未受伤角色体力与条件"..
  "相差1，你可以先令其执行以下一项使其达到条件再对其发动此技能：减1点体力上限；加1点体力上限并回复1点体力。",
  ["lingling__quche"] = "驱车",
  [":lingling__quche"] = "出牌阶段限一次，你可以选择令所有角色：各摸两张牌，然后手牌最多的角色各摸一张牌；各弃置两张牌，然后手牌最少的角色"..
  "各弃置一张牌。"..
  "<br><br> <font color = '#a40000'>天崩地坼，掀翻一个世界。",
  ["@lingling__julun"] = "巨轮",
  ["#lingling__julun1-invoke"] = "巨轮：对一名体力为%arg的角色造成1点伤害",
  ["#lingling__julun2-invoke"] = "巨轮：令一名角色调整体力上限和体力值至%arg，对其造成1点伤害",
  ["#lingling__quche"] = "驱车：令所有角色各摸/弃两张牌，手牌数最多/少的角色各摸/弃一张牌",
  ["discard2"] = "弃两张牌",
}

local lvbuwei = General(extension, "lingling__lvbuwei", "qin", 3)
local qihuo = fk.CreateTriggerSkill{
  name = "lingling__qihuo",
  anim_type = "special",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and not player:isNude()
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local tos, cards = room:askForChooseCardsAndPlayers(player, 1, 2, table.map(room.alive_players, Util.IdMapper), 1, 1, nil,
      "#lingling__qihuo-invoke", self.name, true, false)
    if #tos == 1 and #cards > 0 then
      self.cost_data = {tos = tos, cards = cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    room:setPlayerMark(player, self.name, {to.id, self.cost_data.cards})
    to:addToPile("$lingling__qihuo", self.cost_data.cards, false, self.name, player.id, {})
    if not to.dead and not player.dead and not to:isNude() and to ~= player then
      local cards = room:askForCard(to, 1, 999, true, self.name, true, nil, "#lingling__qihuo-give:"..player.id)
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonGive, self.name, nil, false, to.id)
      end
    end
  end,
}
local qihuo_delay = fk.CreateTriggerSkill{
  name = "#lingling__qihuo_delay",
  mute = true,
  events = {fk.Damaged, fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if event == fk.Damaged then
      return #target:getPile("$lingling__qihuo") > 0
    elseif event == fk.TurnStart then
      return target == player and player:getMark("lingling__qihuo") ~= 0
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Damaged then
      if player:getMark("lingling__qihuo")[1] == target.id then
        player:broadcastSkillInvoke("lingling__qihuo")
        room:notifySkillInvoked(player, "lingling__qihuo", "negative")
      end
      room:moveCardTo(target:getPile("$lingling__qihuo"), Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile,
        "lingling__qihuo", nil, true)
    elseif event == fk.TurnStart then
      local to = room:getPlayerById(player:getMark("lingling__qihuo")[1])
      if to.dead then return end
      local cards = table.filter(to:getPile("$lingling__qihuo"), function (id)
        return table.contains(player:getMark("lingling__qihuo")[2], id)
      end)
      if #cards == 0 then return end
      player:broadcastSkillInvoke("lingling__qihuo")
      room:notifySkillInvoked(player, "lingling__qihuo", "drawcard")
      room:moveCardTo(cards, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, "lingling__qihuo", nil, true)
      if player.dead then return end
      player:drawCards(2 * #cards, "lingling__qihuo")
      if player.dead then return end
      if player.maxHp < 6 then
        room:changeMaxHp(player, 1)
        if player.dead then return end
      end
      if player:isWounded() then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = "lingling__qihuo",
        }
      end
    end
  end,
}
local huisheng = fk.CreateTriggerSkill{
  name = "lingling__huisheng",
  anim_type = "defensive",
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target and target ~= player and #player:getCardIds("he") > 1 and not target.dead
  end,
  on_cost = function (self, event, target, player, data)
    local cards = player.room:askForCard(player, 2, 2, true, self.name, true, nil,
      "#lingling__huisheng-give:"..target.id..":"..data.to.id)
    if #cards > 0 then
      self.cost_data = {tos = {target.id}, cards = cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:moveCardTo(self.cost_data.cards, Card.PlayerHand, target, fk.ReasonGive, self.name, nil, false, player.id)
    return true
  end,
}
qihuo:addRelatedSkill(qihuo_delay)
lvbuwei:addSkill(qihuo)
lvbuwei:addSkill(huisheng)
Fk:loadTranslationTable{
  ["lingling__lvbuwei"] = "吕不韦",
  ["#lingling__lvbuwei"] = "悬金钓奇",
  ["illustrator:lingling__lvbuwei"] = "珊瑚虫",
  ["designer:lingling__lvbuwei"] = "伶",

  ["lingling__qihuo"] = "奇货",
  [":lingling__qihuo"] = "回合结束时，你可以将至多两张牌扣置于一名角色武将牌旁，其可以交给你任意张牌。当其受到伤害后移去这些牌，"..
  "下回合开始时，若这些牌未移去，你移去这些牌摸两倍的牌、加1点体力上限并回复1点体力（至多加至6）。",
  ["lingling__huisheng"] = "贿生",
  [":lingling__huisheng"] = "当一名角色造成伤害时，你可以交给伤害来源两张牌防止之。"..
  "<br><br> <font color = '#a40000'>十年富贵随轻覆，奇货元来祸更奇。",
  ["#lingling__qihuo-invoke"] = "奇货：将至多两张牌扣置为一名角色的“奇货”牌",
  ["$lingling__qihuo"] = "奇货",
  ["#lingling__qihuo-give"] = "奇货：你可以交给 %src 任意张牌",
  ["#lingling__qihuo_delay"] = "奇货",
  ["#lingling__huisheng-give"] = "贿生：是否交给 %src 两张牌，防止其对 %dest 造成的伤害？",
}

local baiqi = General(extension, "lingling__baiqi", "qin", 4)
local rentu = fk.CreateTriggerSkill{
  name = "lingling__rentu",
  anim_type = "offensive",
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and data.to ~= player and
      data.card and not data.card.multiple_targets then
      if data.to.dead then
        return data.card.trueName == "slash" and player.maxHp < 6
      else
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if data.card.trueName == "slash" then
      local all_choices = {"lingling__rentu_minus::"..data.to.id, "lingling__rentu_add", "Cancel"}
      local choices = table.simpleClone(all_choices)
      if player.maxHp >= 6 then
        table.removeOne(choices, "lingling__rentu_add")
      end
      if data.to.dead then
        table.remove(choices, 1)
      end
      local choice = room:askForChoice(player, choices, self.name, "#lingling__rentu-choice::"..data.to.id, false, all_choices)
      if choice ~= "Cancel" then
        if choice == "lingling__rentu_add" then
          self.cost_data = {choice = choice}
        else
          self.cost_data = {tos = {data.to.id}, choice = choice}
        end
        return true
      end
    else
      if room:askForSkillInvoke(player, self.name, nil, "#lingling__rentu-invoke::"..data.to.id) then
        self.cost_data = {tos = {data.to.id}}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice
    if data.card.trueName == "slash" then
      choice = self.cost_data.choice
    else
      local all_choices = {"lingling__rentu_minus2", "lingling__rentu_add2:"..player.id}
      local choices = table.simpleClone(all_choices)
      if player.maxHp >= 6 then
        table.remove(choices, 2)
      end
      choice = room:askForChoice(data.to, choices, self.name, "#lingling__rentu2-choice:"..player.id, false, all_choices)
    end
    if choice:startsWith("lingling__rentu_minus") then
      room:changeMaxHp(data.to, -1)
    else
      room:changeMaxHp(player, 1)
      if player:isWounded() and not player.dead then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name,
        }
      end
    end
  end
}
local rentu_targetmod = fk.CreateTargetModSkill{
  name = "#lingling__rentu_targetmod",
  main_skill = rentu,
  residue_func = function(self, player, skill, scope)
    if player:hasSkill(rentu) and skill.trueName == "slash_skill" and scope == Player.HistoryPhase then
      return 1
    end
  end,
}
local liuhe = fk.CreateActiveSkill{
  name = "lingling__liuhe",
  anim_type = "offensive",
  frequency = Skill.Limited,
  card_num = 0,
  min_target_num = 1,
  prompt = "#lingling__liuhe",
  card_filter = Util.FalseFunc,
  target_filter = function (self, to_select, selected)
    return to_select ~= Self.id
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0 and player.maxHp > 5
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:sortPlayersByAction(effect.tos)
    for _, id in ipairs(effect.tos) do
      local p = room:getPlayerById(id)
      if not p.dead then
        room:damage{
          from = player,
          to = p,
          damage = 1,
          skillName = self.name,
        }
      end
    end
  end,
}
rentu:addRelatedSkill(rentu_targetmod)
baiqi:addSkill(rentu)
baiqi:addSkill(liuhe)
Fk:loadTranslationTable{
  ["lingling__baiqi"] = "白起",
  ["#lingling__baiqi"] = "杀神",
  ["illustrator:lingling__baiqi"] = "珊瑚虫",
  ["designer:lingling__baiqi"] = "伶",

  ["lingling__rentu"] = "人屠",
  [":lingling__rentu"] = "你使用【杀】的次数上限+1。当你使用单体牌对其他角色造成伤害后，你可以令其选择：减1点体力上限；你加1点体力上限并"..
  "回复1点体力（此项只有你体力上限小于6才能选），若为【杀】造成的伤害，改为你选择。",
  ["lingling__liuhe"] = "六合",
  [":lingling__liuhe"] = "限定技，出牌阶段，若你体力上限不小于6，你可以对任意名其他角色各造成1点伤害。"..
  "<br><br> <font color = '#a40000'>夫攻城堕邑，请使武安子。",
  ["#lingling__rentu-choice"] = "人屠：你对 %dest 造成伤害，是否选择一项？",
  ["lingling__rentu_minus"] = "%dest 减1点体力上限",
  ["lingling__rentu_add"] = "你加1点体力上限并回复1点体力",
  ["#lingling__rentu-invoke"] = "人屠：你对 %dest 造成伤害，是否令其选择一项？",
  ["#lingling__rentu2-choice"] = "人屠：%src 对你造成伤害，请选择一项",
  ["lingling__rentu_minus2"] = "你减1点体力上限",
  ["lingling__rentu_add2"] = "%src 加1点体力上限并回复1点体力",
  ["#lingling__liuhe"] = "六合：你可以对任意名其他角色各造成1点伤害！",

  ["$lingling__liuhe1"] = "天恩我秦，统合西东。",
  ["$lingling__liuhe2"] = "以战疲天下雄卒，以灭慑六合残兵！",
}

local shangyang = General(extension, "lingling__shangyang", "qin", 3)
local limus = fk.CreateActiveSkill{
  name = "lingling__limus",
  anim_type = "control",
  card_num = 1,
  target_num = 0,
  prompt = "#lingling__limus",
  can_use = Util.TrueFunc,
  card_filter = function(self, to_select, selected)
    local card = Fk:getCardById(to_select)
    return #selected == 0 and card.suit == Card.Club and
      not Self:isProhibited(Self, Fk:cloneCard("supply_shortage", card.suit, card.number))
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:useVirtualCard("supply_shortage", effect.cards, player, player, self.name, true)
    if player.dead then return end
    player:drawCards(2, self.name)
    if player.dead then return end
    if player.maxHp < 6 then
      room:changeMaxHp(player, 1)
    end
    if player:isWounded() and not player.dead then
      room:recover{
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      }
    end
  end,
}
local bianfa = fk.CreateViewAsSkill{
  name = "lingling__bianfa",
  anim_type = "control",
  pattern = "nullification",
  prompt = "#lingling__bianfa",
  card_filter = function (self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).type == Card.TypeEquip
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard("nullification")
    card.skillName = self.name
    card:addSubcard(cards[1])
    return card
  end,
  enabled_at_response = function (self, player, response)
    return not response
  end,
}
local bianfa_trigger = fk.CreateTriggerSkill{
  name = "#lingling__bianfa_trigger",
  anim_type = "control",
  main_skill = bianfa,
  events = {fk.CardEffectCancelledOut},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(bianfa) and #player.room:canMoveCardInBoard() > 0 then
      local turn_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn)
      return turn_event and turn_event.data[1] == player
    end
  end,
  on_cost = function (self, event, target, player, data)
    local tos = player.room:askForChooseToMoveCardInBoard(player, "#lingling__bianfa-invoke", self.name, true, nil, false)
    if #tos > 0 then
      self.cost_data = {tos = tos}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(self.cost_data.tos, Util.Id2PlayerMapper)
    room:askForMoveCardInBoard(player, targets[1], targets[2], self.name, nil)
  end,
}
bianfa:addRelatedSkill(bianfa_trigger)
shangyang:addSkill(limus)
shangyang:addSkill(bianfa)
Fk:loadTranslationTable{
  ["lingling__shangyang"] = "商鞅",
  ["#lingling__shangyang"] = "尽公图强",
  ["illustrator:lingling__shangyang"] = "珊瑚虫",
  ["designer:lingling__shangyang"] = "伶",

  ["lingling__limus"] = "立木",
  [":lingling__limus"] = "出牌阶段，你可以将一张梅花牌当【兵粮寸断】对你使用，然后你摸两张牌，加1点体力上限并回复1点体力（至多加至6）。",
  ["lingling__bianfa"] = "变法",
  [":lingling__bianfa"] = "你的回合内，当一张牌被抵消后，你可以移动场上一张牌。你可以将装备牌当【无懈可击】使用。"..
  "<br><br> <font color = '#a40000'>法学之巨子，政治家之雄也。",
  ["#lingling__limus"] = "立木：你可以将一张♣牌当【兵粮寸断】对你使用，摸两张牌，加1点体力上限并回复1点体力",
  ["#lingling__bianfa"] = "变法：你可以将装备牌当【无懈可击】使用",
  ["#lingling__bianfa_trigger"] = "变法",
  ["#lingling__bianfa-invoke"] = "变法：你可以移动场上一张牌",
}

local zhaogao = General(extension, "lingling__zhaogao", "qin", 3)
local diandao = fk.CreateTriggerSkill{
  name = "lingling__diandao",
  anim_type = "control",
  events = {fk.PindianCardsDisplayed},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and (player == data.from or data.results[player.id]) and
      player:usedSkillTimes(self.name, Player.HistoryRound) == 0 then
      if player == data.from then
        for _, dat in pairs(data.results) do
          local n = data.fromCard.number - dat.toCard.number
          if n < 0 then
            return true
          elseif n > 0 and (player:isWounded() or player.maxHp < 6) then
            return true
          end
        end
      elseif data.results[player.id] then
        local n = data.results[player.id].toCard.number - data.fromCard.number
        if n < 0 then
          return true
        elseif n > 0 then
          return player:isWounded() or player.maxHp < 6
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets, yes = {}, false
    if player == data.from then
      for id, dat in pairs(data.results) do
        local n = data.fromCard.number - dat.toCard.number
        if n < 0 then
          table.insertIfNeed(targets, id)
        elseif n > 0 and (player:isWounded() or player.maxHp < 6) then
          yes =  true
        end
      end
    elseif data.results[player.id] then
      local n = data.results[player.id].toCard.number - data.fromCard.number
      if n < 0 then
        table.insertIfNeed(targets, data.from.id)
      elseif n > 0 and (player:isWounded() or player.maxHp < 6) then
        yes =  true
      end
    end
    local all_choices = {"lingling__diandao_swap", "lingling__diandao_recover", "Cancel"}
    local choices = table.simpleClone(all_choices)
    if not yes then
      table.remove(choices, 2)
    end
    if #targets == 0 then
      table.remove(choices, 1)
    end
    local choice
    if #choices == 2 then
      choice = choices[1]
    else
      choice = room:askForChoice(player, choices, self.name)
    end
    if choice ~= "Cancel" then
      if choice == "lingling__diandao_recover" then
        if room:askForSkillInvoke(player, self.name, nil, "#lingling__diandao-recover") then
          self.cost_data = nil
          return true
        end
      else
        if #targets == 1 then
          if room:askForSkillInvoke(player, self.name, nil, "#lingling__diandao-invoke::"..targets[1]) then
            self.cost_data = {tos = targets}
            return true
          end
        else
          --FIXME: 目标拼点角色已阵亡则不能以此法选，可能选牌框较好
          local to = room:askForChoosePlayers(player, targets, 1, 1, "#lingling__diandao2-invoke", self.name, true)
          if #to > 0 then
            self.cost_data = {tos = to}
            return true
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data then
      local to = room:getPlayerById(self.cost_data.tos[1])
      if player == data.from then
        data.fromCard, data.results[to.id].toCard = data.results[to.id].toCard, data.fromCard
      else
        data.fromCard, data.results[player.id].toCard = data.results[player.id].toCard, data.fromCard
      end
    else
      if player.maxHp < 6 then
        room:changeMaxHp(player, 1)
      end
      if player:isWounded() and not player.dead then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name,
        }
      end
    end
  end,
}
local dangtong = fk.CreateTriggerSkill{
  name = "lingling__dangtong",
  anim_type = "control",
  events = {fk.AfterCardTargetDeclared},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and data.tos then
      if target == player and table.find(TargetGroup:getRealTargets(data.tos), function (id)
          return id ~= player.id
        end) then
        return table.find(player.room:getUseExtraTargets(data, true), function (id)
          return player:canPindian(player.room:getPlayerById(id))
        end) or table.find(TargetGroup:getRealTargets(data.tos), function (id)
          return id ~= player.id and player:canPindian(player.room:getPlayerById(id))
        end)
      elseif target ~= player and table.contains(TargetGroup:getRealTargets(data.tos), player.id) then
        return table.find(player.room:getUseExtraTargets(data, true), function (id)
          return player:canPindian(player.room:getPlayerById(id))
        end) or player:canPindian(target)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets1 = {}
    local targets2 = table.filter(room:getUseExtraTargets(data, true), function (id)
      return player:canPindian(room:getPlayerById(id))
    end)
    if target == player and table.find(TargetGroup:getRealTargets(data.tos), function (id)
        return id ~= player.id
      end) then
      targets1 = table.filter(TargetGroup:getRealTargets(data.tos), function (id)
        return id ~= player.id and player:canPindian(room:getPlayerById(id))
      end)
    elseif target ~= player and table.contains(TargetGroup:getRealTargets(data.tos), player.id) then
      if player:canPindian(target) then
        targets1 = {target.id}
      end
    end
    room:setPlayerMark(player, "lingling__dangtong-tmp", {targets1, targets2})
    local success, dat = room:askForUseActiveSkill(player, "lingling__dangtong_active",
      "#lingling__dangtong-invoke:::"..data.card:toLogString(), true, nil, false)
    room:setPlayerMark(player, "lingling__dangtong-tmp", 0)
    if success and dat then
      self.cost_data = {tos = dat.targets, choice = dat.interaction}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local pindian = player:pindian({to}, self.name)
    if self.cost_data.choice == "lingling__dangtong1" then
      if pindian.results[to.id].winner == player and not player.dead then
        player:drawCards(1, self.name)
      end
    else
      if pindian.results[to.id].winner ~= to and
        table.contains(room:getUseExtraTargets(data, true), to.id) then
        table.insert(data.tos, {to.id})
      end
    end
  end,
}
local dangtong_active = fk.CreateActiveSkill{
  name = "lingling__dangtong_active",
  card_num = 0,
  target_num = 1,
  interaction = function()
    return UI.ComboBox {choices = {"lingling__dangtong1", "lingling__dangtong2"}}
  end,
  card_filter = Util.FalseFunc,
  target_filter = function (self, to_select, selected)
    local mark = Self:getMark("lingling__dangtong-tmp")
    if #selected == 0 then
      if self.interaction.data == "lingling__dangtong1" then
        return table.contains(mark[1], to_select)
      elseif self.interaction.data == "lingling__dangtong2" then
        return table.contains(mark[2], to_select)
      end
    end
  end,
}
local jiachuan = fk.CreateTriggerSkill{
  name = "lingling__jiachuan",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.PindianResultConfirmed},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if data.from == player then
        return data.fromCard.number > 10
      elseif data.to == player then
      return data.results[player.id].toCard.number > 10
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(2, self.name)
  end,
}
Fk:addSkill(dangtong_active)
zhaogao:addSkill(diandao)
zhaogao:addSkill(dangtong)
zhaogao:addSkill(jiachuan)
Fk:loadTranslationTable{
  ["lingling__zhaogao"] = "赵高",
  ["#lingling__zhaogao"] = "指鹿为马",
  ["illustrator:lingling__zhaogao"] = "珊瑚虫",
  ["designer:lingling__zhaogao"] = "伶",

  ["lingling__diandao"] = "颠倒",
  [":lingling__diandao"] = "每轮限一次，当你拼点牌亮出后，若你点数更小，你可以与其交换拼点牌，若你点数更大，你可以加1点体力上限并回复1点体力"..
  "（至多加至6）。",
  ["lingling__dangtong"] = "党同",
  [":lingling__dangtong"] = "当其他角色使用牌指定你为目标时，或你使用牌指定其他角色为目标时，你可以选择：与其拼点，若你赢则你摸一张牌；"..
  "与另一名能成为此牌目标的角色拼点，若其没赢则其成为额外目标。",
  ["lingling__jiachuan"] = "假传",
  [":lingling__jiachuan"] = "你使用点数大于10的牌拼点后摸两张牌。"..
  "<br><br> <font color = '#a40000'>人神所疾，异代同愤。",
  ["#lingling__diandao-invoke"] = "颠倒：是否与 %dest 交换拼点牌？",
  ["#lingling__diandao2-invoke"] = "颠倒：是否与其中一名角色交换拼点牌？",
  ["#lingling__diandao-recover"] = "颠倒：是否加1点体力上限并回复1点体力？",
  ["lingling__diandao_swap"] = "交换拼点牌",
  ["lingling__diandao_recover"] = "加1点体力上限并回复1点体力",
  ["lingling__dangtong_active"] = "党同",
  ["#lingling__dangtong-invoke"] = "党同：与对方拼点，若赢则摸一张牌；或与另一名角色拼点，其没赢则成为%arg额外目标",
  ["lingling__dangtong1"] = "拼点赢则摸一张牌",
  ["lingling__dangtong2"] = "对方没赢则成为目标",
}

local zhanghan = General(extension, "lingling__zhanghan", "qin", 4)
local duzhu = fk.CreateTriggerSkill{
  name = "lingling__duzhu",
  anim_type = "special",
  frequency = Skill.Limited,
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0 and
      #player.room:getOtherPlayers(player) > 0
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#lingling__duzhu-invoke")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, table.map(room:getOtherPlayers(player), Util.IdMapper))
    for _, p in ipairs(room:getOtherPlayers(player)) do
      if player.dead then return end
      if not p.dead then
        local choice = room:askForChoice(p, {"lingling__duzhu_damage:"..player.id, "lingling__duzhu_draw:"..player.id}, self.name)
        if choice:startsWith("lingling__duzhu_damage") then
          room:damage{
            from = p,
            to = player,
            damage = 1,
            skillName = self.name,
          }
        else
          player:drawCards(2, self.name)
        end
      end
    end
  end,
}
local wanlan = fk.CreateTriggerSkill{
  name = "lingling__wanlan",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.Damage, fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local n = 0
      if event == fk.Damage then
        n = #player.room.logic:getActualDamageEvents(4, function(e)
          return e.data[1].from == player
        end, Player.HistoryTurn)
      elseif event == fk.Damaged then
        n = #player.room.logic:getActualDamageEvents(4, function(e)
          return e.data[1].to == player
        end, Player.HistoryTurn)
      end
      self.cost_data = n
      if n == 2 then
        return true
      elseif n == 3 then
        return player:isWounded()
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data == 2 then
      player:drawCards(1, self.name)
    elseif self.cost_data == 3 then
      room:recover{
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      }
    end
  end,
}
local pingpan = fk.CreateTriggerSkill{
  name = "lingling__pingpan",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_cost = function(self, event, target, player, data)
    local choice = player.room:askForChoice(player, {"lingling__pingpan1", "lingling__pingpan2", "Cancel"}, self.name,
      "#lingling__pingpan-choice")
    if choice ~= "Cancel" then
      self.cost_data = {choice = choice}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "@@"..self.cost_data.choice.."-turn", 1)
  end,

  refresh_events = {fk.Damaged, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if player:hasSkill(self, true) then
      if event == fk.Damaged then
        return target == player and data.from
      elseif event == fk.Deathed then
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Damaged then
      room:addTableMark(player, self.name, data.from.id)
    elseif event == fk.Deathed then
    end
  end,

  on_acquire = function (self, player, is_start)
    local room = player.room
    local targets = {}
    room.logic:getActualDamageEvents(1, function(e)
      local damage = e.data[1]
      if damage.to == player and damage.from then
        table.insertIfNeed(targets, damage.from.id)
      end
    end, Player.HistoryGame)
    room:setPlayerMark(player, self.name, targets)
  end,
}
local pingpan_delay = fk.CreateTriggerSkill{
  name = "#lingling__pingpan_delay",
  anim_type = "offensive",
  events = {fk.AfterCardTargetDeclared, fk.Deathed},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(pingpan) and player:getMark("@@lingling__pingpan1-turn") + player:getMark("@@lingling__pingpan2-turn") > 0 then
      if event == fk.AfterCardTargetDeclared and target == player then
        return target == player and data.card.trueName == "slash" and
          table.find(player.room:getUseExtraTargets(data, true), function (id)
            return table.contains(player:getTableMark("lingling__pingpan"), id)
          end)
      elseif event == fk.Deathed then
        return data.damage and data.damage.from and data.damage.from == player and
          data.damage.card and data.damage.card.trueName == "slash"
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.AfterCardTargetDeclared then
      local room = player.room
      local targets = table.filter(room:getUseExtraTargets(data, true), function (id)
        return table.contains(player:getTableMark("lingling__pingpan"), id)
      end)
      local n = player:getMark("@@lingling__pingpan1-turn") > 0 and 10 or 1
      local tos = room:askForChoosePlayers(player, targets, 1, n,
        "#lingling__pingpan-choose:::"..data.card:toLogString(), "lingling__pingpan", true)
      if #tos > 0 then
        self.cost_data = {tos = tos}
        return true
      end
    elseif event == fk.Deathed then
      self.cost_data = nil
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.AfterCardTargetDeclared then
      table.insertTable(data.tos, table.map(self.cost_data.tos, function (id)
        return {id}
      end))
    elseif event == fk.Deathed then
      local room = player.room
      room:setPlayerMark(player, "@@lingling__pingpan1-turn", 0)
      room:setPlayerMark(player, "@@lingling__pingpan2-turn", 0)
      room:invalidateSkill(player, "lingling__pingpan", "-turn")
      if player.maxHp < 6 then
        room:changeMaxHp(player, 1)
      end
      if player:isWounded() and not player.dead then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = "lingling__pingpan",
        }
      end
    end
  end,
}
local pingpan_targetmod = fk.CreateTargetModSkill{
  name = "#lingling__pingpan_targetmod",
  main_skill = pingpan,
  residue_func = function(self, player, skill, scope)
    if skill.trueName == "slash_skill" and player:getMark("@@lingling__pingpan2-turn") > 0 and scope == Player.HistoryPhase then
      return 1
    end
  end,
  bypass_distances =  function(self, player, skill)
    return player:hasSkill(pingpan) and skill.trueName == "slash_skill"
  end,
}
pingpan:addRelatedSkill(pingpan_delay)
pingpan:addRelatedSkill(pingpan_targetmod)
zhanghan:addSkill(duzhu)
zhanghan:addSkill(wanlan)
zhanghan:addSkill(pingpan)
Fk:loadTranslationTable{
  ["lingling__zhanghan"] = "章邯",
  ["#lingling__zhanghan"] = "再造大秦",
  ["illustrator:lingling__zhanghan"] = "珊瑚虫",
  ["designer:lingling__zhanghan"] = "伶",

  ["lingling__duzhu"] = "独柱",
  [":lingling__duzhu"] = "限定技，回合开始时，你可以令其他角色依次选择：对你造成1点伤害；令你摸两张牌。",
  ["lingling__wanlan"] = "挽澜",
  [":lingling__wanlan"] = "你每回合：第二次受到或造成伤害后，你摸一张牌；第三次受到或造成伤害后，你回复1点体力。",
  ["lingling__pingpan"] = "平叛",
  [":lingling__pingpan"] = "你使用【杀】无距离限制。出牌阶段开始时，你可以选择令你本回合使用【杀】：可以额外指定任意名对你造成过伤害的角色"..
  "为目标；可以额外指定一名对你造成过伤害的角色为目标，且本回合你使用【杀】的次数上限+1。因此杀死一名角色后，你加1点体力上限并回复1点体力"..
  "（至多加至6），然后本回合此技能无效。"..
  "<br><br> <font color = '#a40000'>盖章邯为秦之骁将，邯不败，即秦不亡。",
  ["#lingling__duzhu-invoke"] = "独柱：是否令其他角色依次选择：对你造成1点伤害，或令你摸两张牌？",
  ["lingling__duzhu_damage"] = "对 %src 造成1点伤害",
  ["lingling__duzhu_draw"] = "%src 摸两张牌",
  ["#lingling__pingpan-choice"] = "平叛：你可以选择一项本回合生效",
  ["lingling__pingpan1"] = "使用【杀】额外指定任意名对你造成过伤害的角色为目标",
  ["lingling__pingpan2"] = "使用【杀】额外指定一名对你造成过伤害的角色为目标，次数上限+1",
  ["@@lingling__pingpan1-turn"] = "平叛 任意额外目标",
  ["@@lingling__pingpan2-turn"] = "平叛 一名额外目标",
  ["#lingling__pingpan_delay"] = "平叛",
  ["#lingling__pingpan-choose"] = "平叛：你可以为此%arg额外指定对你造成过伤害的角色为目标",

  ["$lingling__duzhu1"] = "待令严守关中，山东已无王臣。",
  ["$lingling__duzhu2"] = "废怠堕之将，战事或有胜机！",
}

local lisi = General(extension, "lingling__lisi", "qin", 4)
local shangshu = fk.CreateTriggerSkill{
  name = "lingling__shangshu",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.card:isCommonTrick() and not data.card:isVirtual() and
    player.room:getCardArea(data.card) == Card.Processing and
      #player:getPile("$lingling__shangshu") < 9
  end,
  on_use = function(self, event, target, player, data)
    player:addToPile("$lingling__shangshu", data.card, false, self.name, player.id)
  end,
}
local jianzhu = fk.CreateTriggerSkill{
  name = "lingling__jianzhu",
  frequency = Skill.Wake,
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  can_wake = function(self, event, target, player, data)
    return #player:getPile("$lingling__shangshu") > 8
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, 1)
    if player.dead then return end
    if player:isWounded() then
      room:recover{
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      }
    end
    if player.dead then return end
    room:handleAddLoseSkills(player, "lingling__dinggui|lingling__weiji", nil, true, false)
  end,
}
local dinggui = fk.CreateTriggerSkill{
  name = "lingling__dinggui",
  anim_type = "drawcard",
  events = {fk.CardUseFinished, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.CardUseFinished then
        return data.card.type == Card.TypeTrick and not (data.extra_data and data.extra_data.lingling__dinggui) and
          #player:getPile("$lingling__shangshu") > 0
      elseif event == fk.EventPhaseStart then
        return player.phase == Player.Play and not player:isNude()
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.CardUseFinished then
      local cards = table.random(player:getPile("$lingling__shangshu"), 3)
      local card = U.askforChooseCardsAndChoice(player, cards, {"OK"}, self.name, "#lingling__dinggui-prey", {"Cancel"})
      if #card > 0 then
        self.cost_data = {cards = card}
        return true
      end
    elseif event == fk.EventPhaseStart then
      local card = player.room:askForDiscard(player, 1, 1, true, self.name, true, nil, "#lingling__dinggui-discard", true)
      if #card > 0 then
        self.cost_data = {cards = card}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardUseFinished then
      room:moveCardTo(self.cost_data.cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, false, player.id,
      "@@lingling__dinggui-inhand")
    elseif event == fk.EventPhaseStart then
      room:throwCard(self.cost_data.cards, self.name, player, player)
      if player.dead then return end
      local cards = room:getCardsFromPileByRule(".|.|.|.|.|trick", 2, "allPiles")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, false, player.id)
      end
    end
  end,

  refresh_events = {fk.PreCardUse},
  can_refresh = function (self, event, target, player, data)
    return target == player and data.card:getMark("@@lingling__dinggui-inhand") > 0
  end,
  on_refresh = function (self, event, target, player, data)
    data.extra_data = data.extra_data or {}
    data.extra_data.lingling__dinggui = true
    if player:hasSkill("lingling__weiji", true) and player:usedSkillTimes("lingling__weiji", Player.HistoryGame) == 0 and
      player:getMark("@lingling__weiji") < 5 then
      player.room:addPlayerMark(player, "@lingling__weiji", 1)
    end
  end,
}
local weiji = fk.CreateTriggerSkill{
  name = "lingling__weiji",
  frequency = Skill.Wake,
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  can_wake = function(self, event, target, player, data)
    return player:getMark("@lingling__weiji") > 4
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "@lingling__weiji", 0)
    room:changeMaxHp(player, 1)
    if player.dead then return end
    if player:isWounded() then
      room:recover{
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      }
    end
    if player.dead then return end
    room:handleAddLoseSkills(player, "lingling__fenshu", nil, true, false)
  end,
}
local fenshu = fk.CreateActiveSkill{
  name = "lingling__fenshu",
  anim_type = "offensive",
  card_num = 3,
  target_num = 1,
  expand_pile = "$lingling__shangshu",
  prompt = "#lingling__fenshu",
  can_use = function(self, player)
    return #player:getPile("$lingling__shangshu") > 2 and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function(self, to_select, selected)
    return #selected < 3 and table.contains(Self:getPile("$lingling__shangshu"), to_select)
  end,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:moveCardTo(effect.cards, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, self.name, nil, true, player.id)
    if target.dead then return end
    room:damage{
      from = player,
      to = target,
      damage = 1,
      damageType = fk.FireDamage,
      skillName = self.name,
    }
  end,
}
lisi:addSkill(shangshu)
lisi:addSkill(jianzhu)
lisi:addRelatedSkill(dinggui)
lisi:addRelatedSkill(weiji)
lisi:addRelatedSkill(fenshu)
Fk:loadTranslationTable{
  ["lingling__lisi"] = "李斯",
  ["#lingling__lisi"] = "千古一相",
  ["illustrator:lingling__lisi"] = "珊瑚虫",
  ["designer:lingling__lisi"] = "伶",

  ["lingling__shangshu"] = "上书",
  [":lingling__shangshu"] = "当一名角色使用非转化实体锦囊牌结算后，若“书”少于9张，你将之扣置于一旁称为“书”。",
  ["lingling__jianzhu"] = "谏逐",
  [":lingling__jianzhu"] = "觉醒技，回合开始时，若“书”不少于9张，你加1点体力上限，回复1点体力，获得〖定轨〗和〖位极〗。",
  ["lingling__dinggui"] = "定轨",
  [":lingling__dinggui"] = "当你使用不从“书”中获得的锦囊牌后，你可以三选一获得一张“书”，将剩余两张洗回“书”。出牌阶段开始时，你可以弃置一张牌，"..
  "随机获得一张锦囊牌。",
  ["lingling__weiji"] = "位极",
  [":lingling__weiji"] = "觉醒技，回合开始时，若你使用了至少5张“书”中的牌，你加1点体力上限，回复1点体力，获得〖焚书〗。",
  ["lingling__fenshu"] = "焚书",
  [":lingling__fenshu"] = "出牌阶段限一次，你可以移去三张“书”，对一名其他角色造成1点火焰伤害。"..
  "<br><br> <font color = '#a40000'>鼠在所居，人固择地。斯效智力，功立名遂。",
  ["$lingling__shangshu"] = "书",
  ["#lingling__dinggui-prey"] = "定轨：你可以获得一张“书”",
  ["#lingling__dinggui-discard"] = "定轨：你可以弃置一张牌，随机获得一张锦囊牌",
  ["@@lingling__dinggui-inhand"] = "书",
  ["@lingling__weiji"] = "位极",
  ["#lingling__fenshu"] = "焚书：你可以移去三张“书”，对一名其他角色造成1点火焰伤害",

  ["$lingling__jianzhu1"] = "昔周公不拘殷夏之徒，巩周祚有八百，何况大王？",
  ["$lingling__jianzhu2"] = "王者不却众庶，故能明其德。",
  ["$lingling__weiji1"] = "总揣天下枢要，大颁帝言王宪。",
  ["$lingling__weiji2"] = "吾居高台，万般当就。",
}

local mengtian = General(extension, "lingling__mengtian", "qin", 4)
local shebian = fk.CreateTriggerSkill{
  name = "lingling__shebian",
  anim_type = "control",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.trueName == "slash" and data.to ~= player.id
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#lingling__shebian-invoke::"..data.to)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.to)
    local card = room:getCardsFromPileByRule("jink", 1, "allPiles")
    if #card > 0 then
      room:moveCardTo(card, Card.PlayerHand, to, fk.ReasonJustMove, self.name, nil, true, to.id)
      if to.dead or to:isKongcheng() then return end
    end
    local cards = room:askForCardsChosen(player, to, 1, player:distanceTo(to) + 1, "h", self.name,
      "#lingling__shebian-show::"..to.id..":"..(player:distanceTo(to) + 1))
    local n = #table.filter(cards, function (id)
      return Fk:getCardById(id).trueName == "jink"
    end)
    to:showCards(cards)
    if n > 0 and not to.dead then
      n = n + 1
      if player.dead or player.maxHp >= 6 then
        room:askForDiscard(to, n, n, true, self.name, false)
      elseif #room:askForDiscard(to, n, n, true, self.name, true, nil, "#lingling__shebian-ask:"..player.id.."::"..n) == 0 then
        n = n - 1
        room:changeMaxHp(player, n)
        if player.dead then return end
        if player:isWounded() then
          room:recover{
            who = player,
            num = math.min(n, player.maxHp - player.hp),
            recoverBy = player,
            skillName = self.name,
          }
        end
      end
      if not to.dead and math.random() < 0.6 then
        room:loseHp(to, 1, self.name)
      end
    end
  end,
}
local kaidao = fk.CreateTriggerSkill{
  name = "lingling__kaidao",
  anim_type = "support",
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_cost = function (self, event, target, player, data)
    local success, dat = player.room:askForUseActiveSkill(player, "lingling__kaidao_active",
      "#lingling__kaidao-invoke", true, nil, false)
    if success and dat then
      self.cost_data = {tos = dat.targets, choice = dat.interaction}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if self.cost_data.choice == "lingling__kaidao1" then
      room:handleAddLoseSkills(player, "-lingling__kaidao", nil, true, false)
      player:drawCards(2, self.name)
    else
      local to = room:getPlayerById(self.cost_data.tos[1])
      room:changeMaxHp(player, -1)
      if not to.dead then
        room:handleAddLoseSkills(to, "lingling__kaidao", nil, true, false)
      end
    end
  end,
}
local kaidao_attackrange = fk.CreateAttackRangeSkill{
  name = "#lingling__kaidao_attackrange",
  main_skill = kaidao,
  correct_func = function (self, from, to)
    if from:hasSkill(kaidao) then
      return 1
    end
    return 0
  end,
}
local kaidao_active = fk.CreateActiveSkill{
  name = "lingling__kaidao_active",
  card_num = 0,
  min_target_num = 0,
  max_target_num = 1,
  interaction = UI.ComboBox { choices = {"lingling__kaidao1", "lingling__kaidao2"} },
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    if self.interaction.data == "lingling__kaidao1" then
      return false
    else
      return #selected == 0 and to_select ~= Self.id and
        not Fk:currentRoom():getPlayerById(to_select):hasSkill("lingling__kaidao", true)
    end
  end,
  feasible = function (self, selected, selected_cards)
    if self.interaction.data == "lingling__kaidao1" then
      return #selected == 0
    else
      return #selected == 1
    end
  end,
}
kaidao:addRelatedSkill(kaidao_attackrange)
Fk:addSkill(kaidao_active)
mengtian:addSkill(shebian)
mengtian:addSkill(kaidao)
Fk:loadTranslationTable{
  ["lingling__mengtian"] = "蒙恬",
  ["#lingling__mengtian"] = "忠不足相",
  ["illustrator:lingling__mengtian"] = "珊瑚虫",
  ["designer:lingling__mengtian"] = "伶",

  ["lingling__shebian"] = "慑边",
  [":lingling__shebian"] = "当你使用【杀】指定其他角色为目标后，你可以令其获得一张【闪】，然后展示其至多X张手牌（X为你与其的距离+1），"..
  "若有至少一张【闪】，其选择：你加等量体力上限并回复等量体力（此项只有你体力上限小于6才能选）；弃置【闪】数量+1的牌。选择后，"..
  "其有60%几率失去1点体力。",
  ["lingling__kaidao"] = "开道",
  [":lingling__kaidao"] = "你的攻击范围始终+1。回合结束时，你可以失去此技能摸两张牌，或减1点体力上限令一名其他角色获得此技能。"..
  "<br><br> <font color = '#a40000'>蒙氏秦将，内史忠贤。长城首筑，万里安边。",
  ["#lingling__shebian-invoke"] = "慑边：是否对 %dest 发动“慑边”？",
  ["#lingling__shebian-show"] = "慑边：展示 %dest 至多%arg张手牌",
  ["#lingling__shebian-ask"] = "慑边：请弃置%arg张牌，否则 %src 增加体力上限并回复体力",
  ["lingling__kaidao_active"] = "开道",
  ["#lingling__kaidao-invoke"] = "开道：你可以执行一项",
  ["lingling__kaidao1"] = "失去“开道”并摸两张牌",
  ["lingling__kaidao2"] = "减1点体力上限，令一名角色获得“开道”",
}

local wangjian = General(extension, "lingling__wangjian", "qin", 4)
local chizhong = fk.CreateTriggerSkill{
  name = "lingling__chizhong",
  anim_type = "control",
  events = {fk.TargetSpecified, fk.TargetConfirmed, fk.StartPindian},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return end
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      if target == player and data.card.trueName == "slash" and not player:isNude() then
        if event == fk.TargetSpecified then
          return data.to ~= player.id
        elseif event == fk.TargetConfirmed then
          return data.from ~= player.id
        end
      end
    elseif event == fk.StartPindian and #player:getCardIds("e") > 0 then
      if player == data.from then
        return not data.fromCard
      else
        return not (data.results[player.id] and data.results[player.id].toCard)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      local to = event == fk.TargetConfirmed and data.from or data.to
      local cards = room:askForDiscard(player, 1, 999, true, self.name, true, nil,
        "#lingling__chizhong-invoke::"..to, true)
      if #cards > 0 then
        self.cost_data = {tos = {to}, cards = cards}
        return true
      end
    elseif event == fk.StartPindian then
      local cancelable = not player:isKongcheng()
      local card = room:askForCard(player, 1, 1, true, self.name, cancelable, ".|.|.|equip", "#lingling__chizhong-pindian")
      if #card > 0 then
        self.cost_data = {cards = card}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      room:throwCard(self.cost_data.cards, self.name, player, player)
      local to = room:getPlayerById(self.cost_data.tos[1])
      if player.dead or to.dead or to:isKongcheng() then return end
      local ignoreFromKong = #player:getCardIds("e") > 0
      if not player:canPindian(to, ignoreFromKong) then return end
      local pindian = {
        from = player,
        tos = {to},
        reason = self.name,
        fromCard = nil,
        results = {},
        extra_data = {
          lingling__chizhong = #self.cost_data.cards,
        },
      }
      room:pindian(pindian)
      local winner = pindian.results[to.id].winner
      if winner and not winner.dead and winner:getHandcardNum() < 4 then
        winner:drawCards(4 - winner:getHandcardNum(), self.name)
      end
    elseif event == fk.StartPindian then
      local card = Fk:getCardById(self.cost_data.cards[1])
      if player == data.from then
        data.fromCard = card
      else
        data.results[player.id].toCard = card
      end
    end
  end,

  refresh_events = {fk.PindianCardsDisplayed},
  can_refresh = function (self, event, target, player, data)
    return data.reason == self.name and data.results[player.id] and data.extra_data and data.extra_data.lingling__chizhong
  end,
  on_refresh = function (self, event, target, player, data)
    data.results[player.id].toCard.number = math.max(1, data.results[player.id].toCard.number - data.extra_data.lingling__chizhong)
  end,
}
local qinwang = fk.CreateTriggerSkill{
  name = "lingling__qinwang",
  anim_type = "control",
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card and data.card.trueName == "slash" and
      not data.to.dead and not data.to:isKongcheng()
  end,
  on_cost = function(self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#lingling__qinwang-invoke::"..data.to.id) then
      self.cost_data = {tos = {data.to.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    data.to:showCards(data.to:getCardIds("h"))
    if player.dead or data.to.dead then return end
    local cards = table.filter(data.to:getCardIds("he"), function (id)
      return Fk:getCardById(id).number > 7
    end)
    if #cards > 0 then
      if data.to ~= player then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
      end
    else
      if player.maxHp < 6 then
        room:changeMaxHp(player, 1)
        if player.dead then return end
      end
      if player:isWounded() then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name,
        }
      end
    end
  end,
}
wangjian:addSkill(chizhong)
wangjian:addSkill(qinwang)
Fk:loadTranslationTable{
  ["lingling__wangjian"] = "王翦",
  ["#lingling__wangjian"] = "功盖六国",
  ["illustrator:lingling__wangjian"] = "珊瑚虫",
  ["designer:lingling__wangjian"] = "伶",

  ["lingling__chizhong"] = "持重",
  [":lingling__chizhong"] = "当你使用【杀】指定目标后，或其他角色使用【杀】指定你为目标后，你可以弃置任意张牌，然后与其拼点，"..
  "其此次拼点牌的点数-X（X为你弃牌数），赢者摸牌至四张。你可以用装备区的牌拼点。",
  ["lingling__qinwang"] = "擒王",
  [":lingling__qinwang"] = "当你使用【杀】造成伤害后，你可以展示其所有手牌，获得其点数大于7的所有牌，若没有点数大于7的牌，"..
  "你加1点体力上限并回复1点体力（至多加至6）。"..
  "<br><br> <font color = '#a40000'>将军料敌元非怯，能使君王促驾来。",
  ["#lingling__chizhong-invoke"] = "持重：你可以弃置任意张牌，然后与 %dest 拼点，赢者摸牌至四张",
  ["#lingling__chizhong-pindian"] = "持重：你可以用装备区的牌拼点",
  ["#lingling__qinwang-invoke"] = "擒王：是否令 %dest 展示所有手牌？",
}

local xiangyu = General(extension, "lingling__xiangyu", "chu", 5)
local shenyong = fk.CreateTriggerSkill {
  name = "lingling__shenyong",
  events = {fk.BeforeDrawCard, fk.EventPhaseStart, fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      if event == fk.BeforeDrawCard then
        return data.skillName == "ex_nihilo" and player.drank > 0
      elseif event == fk.EventPhaseStart then
        return player.phase == Player.Draw
      else
        if data.card and data.card.name == "duel" and not data.chain then
          return player.drank > 0
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then 
      local can = {}
      local slash = room:getCardsFromPileByRule("slash",3,"allPiles")
      local wuzhong = room:getCardsFromPileByRule("ex_nihilo",1,"allPiles")
      local jiu = room:getCardsFromPileByRule("analeptic",2,"allPiles")
      local duel = room:getCardsFromPileByRule("duel",1,"allPiles")
      if #slash>2 then
        table.insert(can,"#lingling__shenyong-slash")
      end
      if #duel>0 then
        table.insert(can,"#lingling__shenyong-duel")
      end
      if #wuzhong>0 then
        table.insert(can,"#lingling__shenyong-wuzhong")
      end
      if #jiu>1 then
        table.insert(can,"#lingling__shenyong-jiu")
      end
      if #can>1 then
        local getcards = {}
        local random = table.random(can,2)
        for _, gname in ipairs(random)do
          if gname == "#lingling__shenyong-slash" then
            table.insertTable(getcards,{slash[1],slash[2],slash[3]})
          elseif gname == "#lingling__shenyong-duel" then
            table.insert(getcards,duel[1])
          elseif gname == "#lingling__shenyong-wuzhong"then
            table.insert(getcards,wuzhong[1])
          else
            table.insertTable(getcards,{jiu[1],jiu[2]})
          end
        end
        if #getcards>0 then
          room:sendLog({
            type = "#lingling__xiangyu_random",
            from = player.id,
            arg2 = random[1],
            arg3 = random[2],
            toast = true,
          })
          player.room:moveCards({
            ids = getcards,
            to = player.id,
            toArea = Card.PlayerHand,
            moveReason = fk.ReasonPrey,
            proposer = player.id,
            skillName = self.name,
          })
        end
      else
      room:sendLog({
        type = "#lingling__xiangyu_fail",
        from = player.id,
        toast = true,
      })
    end
      return true
    else
      player.drank = 0
      room:broadcastProperty(player, "drank")
      if event == fk.BeforeDrawCard then
        data.num =data.num+2
      else
        data.damage = data.damage+1
      end
    end
  end,
}
local guaduan = fk.CreateTriggerSkill{
  name = "lingling__guaduan",
  anim_type = "masochism",
  frequency = Skill.Compulsory,
  events = {fk.Damaged},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      table.find(player:getCardIds("h"), function(id)
          return Fk:getCardById(id).trueName == "slash" and not player:prohibitDiscard(id)
      end)
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local cards = table.filter(player:getCardIds("h"), function(id)
      return Fk:getCardById(id).trueName == "slash" and not player:prohibitDiscard(id)
  end)
    room:throwCard(cards, self.name, player, player)
    if not player.dead then
      player:drawCards(#cards, self.name)
    end
  end,
}
xiangyu:addSkill(shenyong)
xiangyu:addSkill(guaduan)
Fk:loadTranslationTable{
  ["lingling__xiangyu"] = "项羽",
  ["#lingling__xiangyu"] = "千古无二",
  ["illustrator:lingling__xiangyu"] = "珊瑚虫",
  ["designer:lingling__xiangyu"] = "伶",

  ["lingling__shenyong"] = "神勇",
  [":lingling__shenyong"] = "摸牌阶段，你改为从以下项中随机获得不同两项：1.一张【决斗】；2.一张【无中生有】；3.两张【酒】；4.三张【杀】。"..
  "你因【无中生有】摸牌时，若你为醉酒状态，消耗此状态多摸两张牌。你使用【决斗】对目标造成伤害时，若你为醉酒状态，消耗此状态令伤害+1。",
  ["lingling__guaduan"] = "寡断",
  [":lingling__guaduan"] = "当你受到伤害后，你弃置手牌中的【杀】并摸等量张牌。"..
  "<br><br> <font color = '#a40000'>楚虽三户，亡秦必楚。",
  ["#lingling__shenyong-duel"] = "一张【决斗】",
  ["#lingling__shenyong-wuzhong"] = "一张【无中生有】",
  ["#lingling__shenyong-jiu"] = "两张【酒】",
  ["#lingling__shenyong-slash"] = "三张【杀】",
  ["#lingling__xiangyu_random"]="%from 从牌堆中获得了 %arg2 和 %arg3 ",
  ["#lingling__xiangyu_less"]="%from 颓势尽显，只获得了 %arg2 ",
  ["#lingling__xiangyu_fail"]="天欲亡汝！ %from 因牌堆和弃牌堆无法提供所需牌而兵尽粮绝！西楚霸王变王八~ ",
}

return extension
